package com.jiayou.session

import com.jiayou.AuthenticatePackage
import com.jiayou.Protocol
import com.jiayou.emnu.FrameType
import com.jiayou.tool.byteArrayToObject
import com.sun.org.apache.xpath.internal.operations.Bool
import io.ktor.network.sockets.*
import io.ktor.utils.io.*
import java.io.Serializable
import kotlin.concurrent.thread

/**
 * 客户端session抽象
 *  T  ->  实际传递数据类型
 *  T1 ->  认证身份类型
 *  T2 ->  认证凭证类型
 */
interface ClientSocketSession<T : Serializable, T1 : Serializable, T2 : Serializable> {
    var authenticatePackage: AuthenticatePackage<T, T1, T2>?

    //连接打开回调
    suspend fun onOpen(socket: Socket, output: ByteWriteChannel, input: ByteReadChannel)

    //收到消息的回调
    suspend fun onMessage(socket: Socket, output: ByteWriteChannel, input: ByteReadChannel, protocol: (Protocol<T, T1, T2>) -> Unit): Boolean {
        input.awaitContent()
        if (input.availableForRead == 0) return false
        val availableLength = input.readInt()
        val byteArray = ByteArray(availableLength)
        input.readFully(byteArray, 0, availableLength)
        val protocolRec: Protocol<T, T1, T2>? = byteArrayToObject(byteArray)
        if (protocolRec != null) {
            //用户监听消息回调
            protocol(protocolRec)
            //如果服务端发来的认证失败或关闭连接帧，则关闭socket连接
            when {
                protocolRec.getFrameType() == FrameType.AUTHENTICATIONSUCCESS -> {
                    DefaultClientSocketSession.logger.info("authentication success!")
                    return true
                }
                protocolRec.getFrameType() == FrameType.AUTHENTICATIONFAILD -> {
                    DefaultClientSocketSession.logger.info("authentication faild!")
                    thread { socket.close() }
                    return false
                }
                protocolRec.getFrameType() == FrameType.CLOSE -> {
                    DefaultClientSocketSession.logger.info("connection has bean closed by ktor-server!")
                    thread { socket.close() }
                    return false
                }
                protocolRec.getFrameType() == FrameType.REPEATUSER -> {
                    DefaultClientSocketSession.logger.info("your identity has bean logined!")
                    thread { socket.close() }
                    return false
                }
            }
        }
        return true
    }

    //等待连接关闭
    suspend fun onWaitClosed(socket: Socket)

    //连接关闭回调
    fun onError(socket: Socket)

}